// API使用Hook
// 提供React组件中使用API的便捷方式

import { useState, useEffect, useCallback, useRef } from 'react';
import { apiClient, RequestConfig, ApiError } from '../services/api/ApiClient';

// Hook状态接口
export interface ApiState<T> {
  data: T | null;
  loading: boolean;
  error: ApiError | null;
  lastUpdated: number | null;
}

// Hook配置接口
export interface UseApiConfig extends RequestConfig {
  immediate?: boolean;
  onSuccess?: (data: any) => void;
  onError?: (error: ApiError) => void;
  deps?: any[];
  refreshInterval?: number;
  staleTime?: number;
}

// 基础API Hook
export function useApi<T = any>(
  command: string,
  args?: Record<string, any>,
  config: UseApiConfig = {}
) {
  const {
    immediate = true,
    onSuccess,
    onError,
    deps = [],
    refreshInterval,
    staleTime = 0,
    ...requestConfig
  } = config;

  const [state, setState] = useState<ApiState<T>>({
    data: null,
    loading: false,
    error: null,
    lastUpdated: null,
  });

  const abortControllerRef = useRef<AbortController | null>(null);
  const refreshIntervalRef = useRef<NodeJS.Timeout | null>(null);

  // 执行API调用
  const execute = useCallback(
    async (overrideArgs?: Record<string, any>) => {
      // 取消之前的请求
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }

      // 创建新的AbortController
      abortControllerRef.current = new AbortController();

      setState(prev => ({ ...prev, loading: true, error: null }));

      try {
        const finalArgs = { ...args, ...overrideArgs };
        const result = await apiClient.invoke<T>(
          command,
          finalArgs,
          {
            ...requestConfig,
            signal: abortControllerRef.current.signal,
          }
        );

        setState({
          data: result,
          loading: false,
          error: null,
          lastUpdated: Date.now(),
        });

        if (onSuccess) {
          onSuccess(result);
        }

        return result;
      } catch (error) {
        const apiError = error instanceof ApiError ? error : new ApiError({
          code: 'UNKNOWN_ERROR',
          message: error instanceof Error ? error.message : 'Unknown error',
          timestamp: new Date().toISOString(),
        });

        setState({
          data: null,
          loading: false,
          error: apiError,
          lastUpdated: Date.now(),
        });

        if (onError) {
          onError(apiError);
        }

        throw apiError;
      }
    },
    [command, JSON.stringify(args), JSON.stringify(requestConfig), onSuccess, onError]
  );

  // 刷新数据
  const refresh = useCallback(() => {
    return execute();
  }, [execute]);

  // 检查数据是否过期
  const isStale = useCallback(() => {
    if (!state.lastUpdated || staleTime === 0) return false;
    return Date.now() - state.lastUpdated > staleTime;
  }, [state.lastUpdated, staleTime]);

  // 自动执行
  useEffect(() => {
    if (immediate) {
      execute();
    }
  }, [immediate, ...deps]);

  // 设置刷新间隔
  useEffect(() => {
    if (refreshInterval && refreshInterval > 0) {
      refreshIntervalRef.current = setInterval(() => {
        if (!state.loading) {
          execute();
        }
      }, refreshInterval);

      return () => {
        if (refreshIntervalRef.current) {
          clearInterval(refreshIntervalRef.current);
        }
      };
    }
  }, [refreshInterval, execute, state.loading]);

  // 清理
  useEffect(() => {
    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
      if (refreshIntervalRef.current) {
        clearInterval(refreshIntervalRef.current);
      }
    };
  }, []);

  return {
    ...state,
    execute,
    refresh,
    isStale: isStale(),
  };
}

// 文件系统API Hook
export function useFileSystem() {
  const readFile = useCallback((path: string, config?: UseApiConfig) => {
    return useApi<string>('read_file', { path }, config);
  }, []);

  const writeFile = useCallback((path: string, content: string, config?: UseApiConfig) => {
    return useApi('write_file', { path, content }, { ...config, immediate: false });
  }, []);

  const readDirectory = useCallback((path: string, config?: UseApiConfig) => {
    return useApi('read_directory', { path }, config);
  }, []);

  return {
    readFile,
    writeFile,
    readDirectory,
  };
}

// CodeGraph API Hook
export function useCodeGraph() {
  const queryGraph = useCallback((query: any, config?: UseApiConfig) => {
    return useApi('query_graph', { query }, config);
  }, []);

  const getGraphStats = useCallback((graphId?: string, config?: UseApiConfig) => {
    return useApi('get_graph_stats', { graphId }, config);
  }, []);

  const getNodeDetails = useCallback((nodeId: string, config?: UseApiConfig) => {
    return useApi('get_node_details', { nodeId }, config);
  }, []);

  return {
    queryGraph,
    getGraphStats,
    getNodeDetails,
  };
}

// LSP API Hook
export function useLsp() {
  const getCompletion = useCallback((
    filePath: string,
    position: any,
    language: string,
    config?: UseApiConfig
  ) => {
    return useApi('lsp_completion', { filePath, position, language }, {
      ...config,
      immediate: false,
    });
  }, []);

  const getHover = useCallback((
    filePath: string,
    position: any,
    language: string,
    config?: UseApiConfig
  ) => {
    return useApi('lsp_hover', { filePath, position, language }, {
      ...config,
      immediate: false,
    });
  }, []);

  const getDiagnostics = useCallback((
    filePath: string,
    language: string,
    config?: UseApiConfig
  ) => {
    return useApi('lsp_diagnostics', { filePath, language }, config);
  }, []);

  return {
    getCompletion,
    getHover,
    getDiagnostics,
  };
}

// 批量API Hook
export function useBatchApi<T = any>(
  requests: Array<{
    command: string;
    args?: Record<string, any>;
    config?: RequestConfig;
  }>,
  config: UseApiConfig = {}
) {
  const [state, setState] = useState<ApiState<T[]>>({
    data: null,
    loading: false,
    error: null,
    lastUpdated: null,
  });

  const execute = useCallback(async () => {
    setState(prev => ({ ...prev, loading: true, error: null }));

    try {
      const results = await apiClient.batch<T>(requests);
      
      setState({
        data: results,
        loading: false,
        error: null,
        lastUpdated: Date.now(),
      });

      return results;
    } catch (error) {
      const apiError = error instanceof ApiError ? error : new ApiError({
        code: 'BATCH_ERROR',
        message: error instanceof Error ? error.message : 'Batch operation failed',
        timestamp: new Date().toISOString(),
      });

      setState({
        data: null,
        loading: false,
        error: apiError,
        lastUpdated: Date.now(),
      });

      throw apiError;
    }
  }, [JSON.stringify(requests)]);

  useEffect(() => {
    if (config.immediate !== false) {
      execute();
    }
  }, [execute, config.immediate]);

  return {
    ...state,
    execute,
  };
}

// 实时数据Hook
export function useRealtimeApi<T = any>(
  eventName: string,
  config: {
    onData?: (data: T) => void;
    onError?: (error: Error) => void;
  } = {}
) {
  const [data, setData] = useState<T | null>(null);
  const [connected, setConnected] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    let unlisten: (() => void) | null = null;

    const connect = async () => {
      try {
        unlisten = await apiClient.listen<T>(eventName, (data) => {
          setData(data);
          setError(null);
          if (config.onData) {
            config.onData(data);
          }
        });

        setConnected(true);
        setError(null);
      } catch (error) {
        const err = error instanceof Error ? error : new Error('Connection failed');
        setError(err);
        setConnected(false);
        if (config.onError) {
          config.onError(err);
        }
      }
    };

    connect();

    return () => {
      if (unlisten) {
        unlisten();
      }
      setConnected(false);
    };
  }, [eventName, config.onData, config.onError]);

  return {
    data,
    connected,
    error,
  };
}

// 导出所有Hook
export {
  useApi as default,
};
